﻿using System;

namespace SeqQueue
{
	public class Program
	{
		static void Main(string[] args)
		{
			
			SeqQueue<Student> seqQueue=new SeqQueue<Student>();
			SeqQueueClass queueManage=new SeqQueueClass();
			Console.WriteLine("目前队列是否为空:"+queueManage.SeqQueueIsEmpty(seqQueue)+"\n");
			Console.WriteLine("将Id=1和Id=2的实体加入队列");
			queueManage.SeqQueueIn(seqQueue, new Student() {Id = 1, Age = 23, Name = "小然"});
			queueManage.SeqQueueIn(seqQueue, new Student() { Id = 2, Age = 22, Name = "allen" });
			Display(seqQueue);
			Console.WriteLine("将队头出队");
			//将队头出队
			var student1 = queueManage.SeqQueueOut(seqQueue);
			Display(seqQueue);
			Console.WriteLine("获取队顶元素");
			//获取队顶元素
			var student2 = queueManage.SeqQueuePeek(seqQueue);
			DisplayStudent(student2);
			Console.ReadLine();
		}

		static void Display(SeqQueue<Student> seqQueue )
		{
			Console.WriteLine("*************************队列数据开始**************************");
			for (int i = seqQueue.head; i < seqQueue.tail; i++)
			{
				Console.WriteLine("Id:"+seqQueue.data[i].Id+",Name:"+seqQueue.data[i].Name+",Age:"+seqQueue.data[i].Age);
			}
			Console.WriteLine("*************************队列数据结束**************************");
		}

		static void DisplayStudent(Student student)
		{
			Console.WriteLine("*************************实体数据开始**************************");
			Console.WriteLine("Id:" + student.Id + ",Name:" + student.Name + ",Age:" + student.Age);
			Console.WriteLine("*************************实体数据结束**************************");
		}

	}

	#region 学生数据实体

	public class Student
	{
		public int Id { get; set; }
		public string Name { get; set; }
		public int Age { get; set; }
	}

	#endregion

	#region 队列的数据结构

	/// <summary>
	/// 队列的数据结构
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class SeqQueue<T>
	{
		private const int _maxSize = 100;
		public int MaxSize
		{
			get { return _maxSize; }
		}

		//顺序队列的存储长度
		public T[] data=new T[_maxSize];

		//头指针
		public int head;
		//尾指针
		public int tail;
	}

	#endregion

	#region 队列的基本操作

	public class SeqQueueClass
	{
		#region 队列的初始化操作

		public SeqQueue<T> SeqQueueInit<T>(SeqQueue<T> seqQueue)
		{
			seqQueue.head = 0;
			seqQueue.tail = 0;
			return seqQueue;
		}

		#endregion

		#region 队列是否为空

		public bool SeqQueueIsEmpty<T>(SeqQueue<T> seqQueue)
		{
			//如果两指针重合，说明队列已经清空
			if (seqQueue.head==seqQueue.tail)
			{
				return true;
			}
			return false;
		}

		#endregion

		#region 队列是否已满

		public bool SeqQueueIsFull<T>(SeqQueue<T> seqQueue)
		{
			//如果尾指针到达数组的末尾，说明队列已经满
			if (seqQueue.tail == seqQueue.MaxSize)
			{
				return true;
			}
			return false;
		}

		#endregion

		#region 队列元素入队

		public SeqQueue<T> SeqQueueIn<T>(SeqQueue<T> seqQueue,T data)
		{
			//如果队列已经满，则不能进行入队操作
			if (SeqQueueIsFull(seqQueue))
			{
				throw new Exception("队列已经满了，不能入队操作");
			}
			//入队操作
			seqQueue.data[seqQueue.tail++] = data;
			return seqQueue;
		}

		#endregion

		#region 队列元素出队

		public T SeqQueueOut<T>(SeqQueue<T> seqQueue)
		{
			//如果队列为空，则不能进行出队操作
			if (SeqQueueIsEmpty(seqQueue))
			{
				throw new Exception("队列为空，不能出队操作");
			}
			//入队操作
			var single = seqQueue.data[seqQueue.head];
			seqQueue.data[seqQueue.head++] = default(T);
			return single;
		}

		#endregion

		#region 获取队头元素

		public T SeqQueuePeek<T>(SeqQueue<T> seqQueue)
		{
			//如果队列为空，则不能进行出队操作
			if (SeqQueueIsEmpty(seqQueue))
			{
				throw new Exception("队列为空，不能出队操作");
			}
			//获取队头元素
			return seqQueue.data[seqQueue.head];
		}

		#endregion

		#region 获取队列长度

		public int SeqQueueLen<T>(SeqQueue<T> seqQueue)
		{
			return seqQueue.tail - seqQueue.head;
		}

		#endregion
	}

	#endregion
}
